#pragma region 【算法3 - 10】稀疏矩阵转置
SPMatrix *TransM2(SPMatrix *A)
{
    SPMatrix *B;
    int i, j, k;
    int num[n + 1], cpot[n + 1]; //元素个数
    B=(SPMatrix *)malloc(sizeof(SPMatrix));
    B->mu=A->nu;B->nu=A->mu;B->tu=A->tu;
    if (B->tu > 0)               //有非零元素则转换
    {
        for (i = 1; i <= A->nu; i++)
            num[i] = 0;
        for (i = 1; i <= A->tu; i++) //求矩阵A中每一列非零元素的个数
        {
            j = A->data[i].j;
            num[j]++;
        }
        cpot[1] = 1; //求矩阵A中每一列第一个非零元素在B.data中的位置
        for (i = 2; i <= A->nu; i++)
            cpot[i] = cpot[i - 1] + num[i - 1];
        for (i = 1; i <= (A->tu); i++) //扫描三元组表
        {
            j = A->data[i].j; //当前三元组的列号
            k = cpot[j];      //当前三元组在B.data中的位置
            B->data[k].i = A->data[i].j;
            B->data[k].j = A->data[i].i;
            B->data[k].v = A->data[i].v;
            cpot[j]++;
        }
    }
    return B; //返回的是转置矩阵的指针
}
#pragma endregion
#pragma region 【算法3 - 11] 稀疏矩阵的乘积算法
SPMatrix *MulSMatrix(SPMatrix *A, SPMatrix *B)
{
    //稀疏矩阵A(m1× n1)和B(m2× n2) 用三元组表存储，求A×B
    SPMatrix *C; //乘积矩阵的指针
    int p, q, i, j, t, k;
    DataType temp[n + 1]; 
    int num[B->mu + 1], rpot[B->mu + 1];
    if (A->nu != B->mu)
        return NULL;                          //A的列与B的行不相等，错误，返回空指针
    C = (SPMatrix *)malloc(sizeof(SPMatrix)); //申请C矩阵的存储空间
    C->mu = A->mu;
    C->nu = B->nu;
    if (A->tu * B->tu == 0)
    {
        C->tu = 0;
        return C; //A、B均为零矩阵，C亦为零矩阵
    }
    for (i = 1; i <= B->mu; i++)
        num[i] = 0; //求矩阵B中每一行非零元素的个数
    for (k = 1; k <= B->tu; k++)
    {
        i = B->data[k].i;
        num[i]++;
    }
    rpot[1] = 0; //求矩阵B中每一行第一个非零元素在B.data中的位置
    for (i = 2; i <= B->mu; i++)
        rpot[i] = rpot[i - 1] + num[i - 1]; //当前C中非零元素的个数
    p = 0;                                  //指示A.data中当前非零元素的位置
    for (i = 1; i <= A->mu; i++)
    {
        memset(temp, 0, sizeof(temp)); //cij的累加器初始化
        while (A->data[p].i == i)      //求第i行的各元素值
        {
            k = A->data[p].j; //A中当前非零元的列号
            if (k < B->mu) 
                t = rpot[k + 1];
            else 
                t = B->tu + 1; //确定B中第k行的非零元在B.data中的下限位置
                                //累加乘积到这个下限就结束了
            for (q = rpot[k]; q < t; q++)
            //B中第k行的每一个非零元素
            {
                j = B->data[q].j;
                temp[j] += A->data[p].v * B->data[q].v;
            }
            p++;
        }
        for (j = 1; j <= B->nu; j++)
            if (temp[j])
            {
                C->data[C->tu].i = i;
                C->data[C->tu].j = j;
                C->data[C->tu].v = temp[j];
                C->tu++;
            }
    }
    return C;
}
#pragma endregion